package com.yc;

import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.ChatMessageDeserializer;
import dev.langchain4j.data.message.ChatMessageSerializer;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.time.Duration;
import java.util.List;

public class PersistentChatMemoryStore implements ChatMemoryStore {

    private static final String REDIS_HOST = "localhost";
    private static final int  REDIS_PORT = 6379;
    //redis键值库,为了区分数据,设计键的前缀
    private static final String REDIS_KEY_PREFIX = "chat:memory";
    private  final JedisPool jedisPool;//连接池

    JedisPoolConfig poolConfig = new JedisPoolConfig();

    public PersistentChatMemoryStore(){

// 连接池大小控制
        poolConfig.setMaxTotal(128);      // 最大连接数（活跃+空闲）
        poolConfig.setMaxIdle(128);       // 最大空闲连接数
        poolConfig.setMinIdle(16);        // 最小空闲连接数
// 连接测试配置
        poolConfig.setTestOnBorrow(true); // 借用连接时测试有效性
        poolConfig.setTestOnReturn(true); // 归还连接时测试有效性
        poolConfig.setTestWhileIdle(true);// 连接空闲时定期测试
// 连接回收策略
        poolConfig.setMinEvictableIdleTimeMillis(Duration.ofSeconds(60).toMillis()); // 连接最小空闲时间（60秒）
        poolConfig.setTimeBetweenEvictionRunsMillis(Duration.ofSeconds(30).toMillis()); // 空闲连接检测周期（30秒）
        poolConfig.setNumTestsPerEvictionRun(3); // 每次检测回收的连接数
// 连接耗尽时的处理
        poolConfig.setBlockWhenExhausted(true); // 连接耗尽时阻塞等待
        this.jedisPool = new JedisPool(poolConfig,REDIS_HOST, REDIS_PORT);
    }

    @Override
    public List<ChatMessage> getMessages(Object memoryId) {
        String key = getKey( memoryId);
        try(Jedis jedis= jedisPool.getResource()){
            String messageJson = jedis.get(key);
            if(messageJson==null || messageJson.isEmpty()){
                return List.of();
            }
            return ChatMessageDeserializer.messagesFromJson(messageJson);
        }
    }

    private String getKey(Object memoryId) {
        return REDIS_KEY_PREFIX  + memoryId.toString();
    }

    @Override
    public void updateMessages(Object o, List<ChatMessage> list) {
        String key = getKey(o);
        try(Jedis jedis = jedisPool.getResource()){
            String messageJson = ChatMessageSerializer.messagesToJson(list);
            jedis.set(key,messageJson);
        }

    }

    @Override
    public void deleteMessages(Object o) {
        String key= getKey(o);
        try(Jedis jedis = jedisPool.getResource()){
            jedis.del(key);
        }

    }
    public void close(){
        if(jedisPool!=null && !jedisPool.isClosed()){
            jedisPool.close();
        }
    }
}
